﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace WPRotator
{
    public partial class FrmMain
    {
        private string fileName;
        private Dictionary<RadioButton, int> intervalArray;
        private Settings settings;

        public FrmMain()
        {
            InitializeComponent();

            intervalArray = new Dictionary<RadioButton, int>()
            {
                {rbt1min, 60000},
                {rbt5min, 180000},
                {rbt15min, 540000},
                {rbt1hr, 3600000},
                {rbt2hr, 7200000},
                {rbt12hr, 43200000},
                {rbt1day, 86400000}
            };

            settings = new Settings(Directory.GetCurrentDirectory(), listboxFiles);
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                notifyIcon.Visible = false;
                if (components != null)
                {
                    components.Dispose();
                }
            }

            base.Dispose(disposing);
        }

        /// <summary>
        /// Change the wallpaper immediately. the method search for any image file in
        /// the directory and enter them into an checked list box
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void EventChangeImage(object sender, System.EventArgs e)
        {
            ChangeImage();
        }

        /// <summary>
        /// add an image file into the checked listbox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void EventOpenFilesDialog(object sender, System.EventArgs e)
        {
            if (ofdAddFiles.ShowDialog() == DialogResult.OK)
            {
                foreach (string fileName in ofdAddFiles.FileNames)
                {
                    settings.PictureList.Add(fileName);
                }

                settings.SaveSettings();
            }

        }

        /// <summary>
        /// form load
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void EventInitializeForm(object sender, System.EventArgs e)
        {
            this.Hide();

            LoadSettings();

            foreach (var item in intervalArray)
            {
                if (item.Value == settings.Interval)
                {
                    item.Key.Checked = true;
                }
            }

            if (settings.PictureList.Count > 0)
            {
                fileName = settings.PictureList.SelectedFile;
            }
            else
            {
                this.Show();
                this.WindowState = FormWindowState.Normal;
            }

            ChangeImage();
        }

        private void LoadSettings()
        {
            settings.LoadSettings();
            chkRandom.Checked = settings.Random;
        }

        /// <summary>
        /// add a selected file type to the listbox
        /// if a new type is suppose to be added - please enter it here
        /// </summary>
        /// <param name="fileType">the file type to be added</param>
        /// <param name="mycheckedListBox"></param>
        /// <returns></returns>
        /// <remarks>TODO: Move to IOHandling</remarks>
        private void AddAllSupportedTypes(string dir)
        {
            AddToCheckedListBox("*.jpg", dir);
            AddToCheckedListBox("*.jpeg", dir);
            AddToCheckedListBox("*.bmp", dir);
            AddToCheckedListBox("*.gif", dir);
        }
        /// <summary>
        /// check the directory , collect all the file name of a certain type
        /// and send them to AddToListBox
        /// </summary>
        /// <param name="fileType">image type file</param>
        /// <param name="dir">the selected directory</param>
        /// <remarks>TODO: Move to IOHandling</remarks>
        private void AddToCheckedListBox(string fileType, string dir)
        {
            string[] dirs = Directory.GetFiles(dir, fileType);

            AddToListBox(dirs);

        }
        /// <summary>
        /// add the string[] to the list box
        /// </summary>
        /// <param name="files">the array of strings to be added</param>
        /// <remarks>TODO: Move to IOHandling</remarks>
        private void AddToListBox(string[] files)
        {
            foreach (string file in files)
            {
                settings.PictureList.Add(file);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="file"></param>
        /// <remarks>TODO: Move to IOHandling</remarks>
        private void AddToListBox(string file)
        {
            {
                settings.PictureList.Add(file);
            }
        }

        /// <summary>
        /// get all the directorys in the specific directory and send them
        /// to check all files and sub directories
        /// </summary>
        /// <param name="strDir">the directory to be searched in</param>
        /// <remarks>TODO: Move to IOHandling</remarks>
        private void CheckDir(string strDir)
        {
            string[] strTempDir = Directory.GetDirectories(strDir);
            foreach (string newstr in strTempDir)
            {
                CheckDir(newstr);
            }

            AddAllSupportedTypes(strDir);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dir"></param>
        /// <returns></returns>
        /// <remarks>TODO: Move to IOHandling. Find a better name</remarks>
        private bool CheckIfDirectory(string dir)
        {
            bool bAns = false;
            if (File.GetAttributes(dir) == FileAttributes.Directory)
                bAns = true;
            return bAns;
        }

        /// <summary>
        /// Delete picture from the listbox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void EventRemoveFileFromList(object sender, System.EventArgs e)
        {
            if (settings.PictureList.Count < 1)
            {
                return;
            }

            if (settings.PictureList.SelectedIndex < 0)
            {
                return;
            }

            settings.PictureList.RemoveSelected();
            fileName = settings.PictureList.SelectedFile;

            settings.SaveSettings();
        }

        /// <summary>
        /// Set the new BMP in the background
        /// </summary>
        /// <remarks>TODO: Parts of this will go to IOHandling. Maybe other parts go to the facade</remarks>
        private void ChangeImage()
        {
            try
            {
                int nResult;

                if (settings.PictureList.Count < 1)
                {
                    return;
                }

                if (chkRandom.Checked == true)
                {
                    int maxIterations = settings.PictureList.Count * 2;

                    do
                    {
                        settings.PictureList.SelectedIndex = (new Random()).Next(settings.PictureList.Count);
                    } while (!settings.PictureList.IsSelectedChecked() && maxIterations-- > 0);
                }
                else
                {
                    int maxIterations = settings.PictureList.Count;

                    do
                    {
                        settings.PictureList.SelectedIndex = (++settings.PictureList.SelectedIndex) % settings.PictureList.Count;
                    } while (!settings.PictureList.IsSelectedChecked() && maxIterations-- > 0);
                }

                if (settings.PictureList.SelectedIndex < 0)
                {
                    settings.PictureList.SelectedIndex = 0;
                }

                if (Path.GetExtension(settings.PictureList.SelectedFile).ToLower() != ".bmp")
                {
                    Bitmap theImage = new Bitmap(settings.PictureList.SelectedFile);
                    fileName = Path.Combine(settings.SettingsPath, "new.bmp");
                    theImage.Save(fileName, System.Drawing.Imaging.ImageFormat.Bmp);
                    theImage.Dispose();
                }

                nResult = WinAPI.SystemParametersInfo(WinAPI.SPI_SETDESKWALLPAPER, 1, fileName, WinAPI.SPIF_SENDCHANGE);

                settings.SaveSettings();
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.ToString());
            }
        }

        private void EventShowAboutDialog(object sender, System.EventArgs e)
        {
            FrmAbout myfrmAbout = new FrmAbout();
            myfrmAbout.ShowDialog(this);
        }

        private void EventDragDropToList(object sender, DragEventArgs e)
        {
            Trace.WriteLine("ListBox Drag enter");

            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

            foreach (string dirfile in files)
            {
                if (CheckIfDirectory(dirfile))
                    CheckDir(dirfile);
                else
                    AddToListBox(dirfile);
            }

            Trace.WriteLine("After Sending to listbox");

        }

        private void EventDragEnterToList(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true)
                e.Effect = DragDropEffects.All;
            Trace.WriteLine("ListBoxDragDrop   ");
        }

        private void EventRestoreWindow(object sender, System.EventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
        }

        private void EventClose(object sender, System.EventArgs e)
        {
            this.Close();
        }

        private void EventResizingFormWindow(object sender, System.EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
            {
                this.Hide();
            }
        }

        private void EventIntervalChanged(object sender, EventArgs e)
        {
            if (sender is RadioButton && ((RadioButton)sender).Checked)
            {
                settings.Interval = intervalArray[(RadioButton)sender];
                timerRotate.Interval = settings.Interval;

                settings.SaveSettings();
            }
        }

        private void EventMouseMoveNotifyIcon(object sender, MouseEventArgs e)
        {
            if (!this.Visible && this.listboxFiles.Items.Count == 0)
            {
                this.notifyIcon.ShowBalloonTip(10000, "No images selected!", "Add some images to the list to\nstart switching them in your desktop!", ToolTipIcon.Warning);
            }
        }

        void EventRandomCheckedChange(object sender, EventArgs e)
        {
            settings.Random = chkRandom.Checked;
            settings.SaveSettings();
        }

        private void EventFormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason != CloseReason.WindowsShutDown)
            {
                DialogResult result = MessageBox.Show(
                    "Closing the application will stop changing your background image.\n\nAre you sure you want to leave?",
                    "Are you sure?", MessageBoxButtons.YesNo,
                    MessageBoxIcon.Warning);

                if (result == DialogResult.No)
                {
                    e.Cancel = true;
                }
            }
        }
    }
}
